
package portal.engine;

import beans.*;
import engine.BIEngine0_1.AlgorithmOperator;
import net.HttpRequest;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import portal.dao.ScheduleJobDetailDao;
import portal.dao.ScheduleSocketLogDao;
import utils.JsonUtil;
import utils.UserLogUtil;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

public class JobOperator {


   private static ScheduleJobDetailDao scheduleJobDetailDao ;

   private static ScheduleSocketLogDao scheduleSocketLogDao ;
   @Autowired
   public void  setScheduleJobDetailDao(ScheduleJobDetailDao sjdd){
	   scheduleJobDetailDao=sjdd;
   }
   @Autowired
	public static void setScheduleSocketLogDao(ScheduleSocketLogDao scheduleSocketLogDao) {
		JobOperator.scheduleSocketLogDao = scheduleSocketLogDao;
	}

	/**
     * By黄振  获得调度job实时运行状态
     * @throws IOException
     */
    public static HttpResultList getScheduleJobFullState(String jobId, String token) throws IOException {
        if(!HttpConfig.fake){
            String callbackResult = HttpRequest.sendGet(
                    HttpConfig.getJobRunningState, "id="+jobId+"&token="+token);
            callbackResult = callbackResult.replaceAll("\\\\\\\\","\\\\");
            callbackResult = callbackResult.replaceAll("\\\\","\\\\\\\\");
            JSONObject result = JSONObject.fromObject(callbackResult);
            return pickFullJobState(result,jobId);
        }else{
            JsonUtil jsonUtil = new JsonUtil();
            String ggResult = jsonUtil.getFullJobState().replaceAll("\\\\", "/");
            JSONObject result = JSONObject.fromObject(ggResult);
            return pickFullJobState(result,jobId);
        }
    }

    public static Boolean updateScheduleJob(String jobId, String token){
        Boolean result = false;
        HttpResultList httpResultList = null;
        try {
            //获取作业详情
            httpResultList = JobOperator.getScheduleJobFullState(jobId, token);
        } catch (IOException e) {
            e.printStackTrace();
        }
        FullJobState fullJobState = (FullJobState) httpResultList.getDatas().get(0);
        String jobStatues = fullJobState.getStatus();
        if(jobStatues.equals("PEND")){
            jobStatues = "ERROR";
        }
        String executionHost = fullJobState.getExecutionHost().split("]")[0].replaceAll("[\"\\[]","");
        String terminationTime = fullJobState.getTerminationTime();
        String cpuUsage = "";
        String remainMem = "";
        //获取节点资源
        HttpResultList hostList = AlgorithmOperator.getJobBasicState(token);
        for (int i = 0; i < hostList.getDatas().size(); i++) {
            BaseResourceState baseResourceState = (BaseResourceState) hostList.getDatas().get(i);
            if(baseResourceState.getHostName().equals(executionHost)){
                cpuUsage = baseResourceState.getUt();
                remainMem = baseResourceState.getMem();
            }
        }
        
        Boolean updateJobDetail = scheduleJobDetailDao.updateScheduleJobDetail(jobId, jobStatues, terminationTime,
                fullJobState.getMemUsage(),fullJobState.getCpuTime(),executionHost,cpuUsage,remainMem);
        Boolean updateSocketJob = scheduleSocketLogDao.updateJobStateByJobId(jobStatues, jobId);
        if (updateJobDetail&&updateSocketJob) {
            System.out.println("作业更新成功");
            result = true;
        }
        return result;
    }

    /**
     * 通过作业id控制调度作业
     * @param jobId
     * @param token
     * @return
     */
    public static HttpResult operateScheduleJob(String operateUrl, String jobId, String token) {
        if(!HttpConfig.fake){

            JSONObject result = JSONObject.fromObject(HttpRequest.sendGet(operateUrl+jobId,
                    "id=" + jobId + "&token=" + token + "&cluster=" + ""));
            if (result.getString("result").equals("success")) {
                return new HttpResult(true, result.getString("message"));
            } else {
                return new HttpResult(false, result.getString("message"));
            }
        }else{
            String id = "操作成功：";
            return new HttpResult(true, id);
        }
    }

    /**
     * @param userName : here not use
     * @param passWord : here not use
     * @return token
     */
    public static HttpResult getToken(String userName, String passWord) {
        if (!HttpConfig.fake) {
            String token = TokenValue.TOKEN.getTokenValue(HttpConfig.userName,HttpConfig.passWord);
            if (token != null) {
                return new HttpResult(true, token);
            } else {
                return new HttpResult(false, "服务器错误！");
            }
        }else{
            return new HttpResult(true,"fakeToken");
        }
    }

    @SuppressWarnings("Duplicates")
    private static HttpResultList pickFullJobState(JSONObject result,String jobId){
        if (result.getString("result").equals("success")) {
            JSONArray data = result.getJSONArray("data");
            List<Object> states = new ArrayList<>();
            for (int i = 0; i < data.size(); i++) {
                FullJobState state = new FullJobState();
                JSONObject oneData = data.getJSONObject(i);
                state.setJobId(jobId);
                state.setIndex(oneData.getString("index"));
                state.setOwner(oneData.getString("owner"));
                //      state.setOwner(oneData.getString("executionHost"));
                state.setStatus(oneData.getString("status"));
                state.setJobName(oneData.getString("name"));
                state.setQueue(oneData.getString("queue"));
                state.setCommand(oneData.getString("command"));
                state.setNewCommand(oneData.getString("newCommand"));
                state.setPendingOrder(oneData.getString("pendingOrder"));
                state.setExecHome(oneData.getString("execHome"));
                state.setExecutionCWD(oneData.getString("executionCWD"));
                state.setExecUsername(oneData.getString("execUsername"));
                state.setCpuTime(oneData.getString("cpuTime"));
                state.setUmask(oneData.getString("umask"));
                state.setCpuFactor(oneData.getString("cpuFactor"));
                state.setExitCode(oneData.getString("exitCode"));
                state.setExecUid(oneData.getString("execUid"));
                state.setPriority(oneData.getString("priority"));
                state.setSubHomeDir(oneData.getString("subHomeDir"));
                state.setSubmitHost(oneData.getString("submitHost"));
                state.setRequestGpuNum(oneData.getString("requestGpuNum"));
                state.setExecutionHost(oneData.getString("executionHost"));
                state.setBindGpu(oneData.getString("bindGPU"));
                state.setReason(oneData.getString("reasons"));
                state.setSumRusage(oneData.getString("sumRusage"));
                state.setHostsRusage(oneData.getString("hostsRusage"));
                state.setRequestResources(oneData.getString("requestResources"));
                state.setHostSpec(oneData.getString("hostSpec"));
                state.setInFile(oneData.getString("inFile"));
                state.setOutFile(oneData.getString("outFile"));
                state.setErrFile(oneData.getString("errFile"));
                state.setChkpntDir(oneData.getString("chkpntDir"));
                state.setPreExecCmd(oneData.getString("preExecCmd"));
                state.setMailUser(oneData.getString("mailUser"));
                state.setProject(oneData.getString("project"));
                state.setLoginShell(oneData.getString("loginShell"));
                state.setDependCond(oneData.getString("dependCond"));
                state.setSlots(oneData.getString("slots"));
                state.setSigValue(oneData.getString("sigValue"));
                state.setMaxNumProcessors(oneData.getString("maxNumProcessors"));
//			 state.setNumProcessors(oneData.getString("maxNumProcessors"));
                state.setUserPriority(oneData.getString("userPriority"));
                state.setAskedHosts(oneData.getString("askedHosts"));
                state.setSubmitTime(oneData.getString("submitTime"));
                state.setExecutionTime(oneData.getString("executionTime"));
                state.setTerminationTime(oneData.getString("terminationTime"));
                state.setReserveTime(oneData.getString("reserveTime"));
                state.setjRusageUpdateTime(oneData.getString("jRusageUpdateTime"));
                state.setPredictedStartTime(oneData.getString("predictedStartTime"));
                state.setArrayJob(oneData.getString("arrayJob"));
                state.setDesktopid(oneData.getString("desktopid"));
                state.setGroup(oneData.getString("group"));
                state.setMemUsage(oneData.getString("memUsage"));
                state.setSwapUsage(oneData.getString("swapUsage"));
                state.setCpuUsage(oneData.getString("cpuUsage"));
                states.add(state);
            }
            return new HttpResultList(true, result.getString("message"), states);
        } else {
            return new HttpResultList(false, result.getString("message"), null);
        }

    }

    /**
     * 查询运行任务的日志文件地址
     * 协议里面data是一个数组，这里只取了数组中的第一个元素
     * {
     *     "result": "success",
     *     "message": null,
     *     "data": [
     *         {
     *             "fileName": "output.6084.txt",
     *             "path": "/apps/jhinno/jhappform/spoolers/jhadmin/cd35183a-a6b5-424d-b_uiAlgorithm_1_jhadmin_1522390330804/output.6084.txt"
     *         }
     *     ]
     * }
     * @return  上面的path对应的字符串值
     */
    public static String queryLogFileUrl(String jobId){
        String result = null;
        String token = TokenValue.TOKEN.getTokenValue(HttpConfig.userName,HttpConfig.passWord);
        if(token!=null)
        {
            //请求格式：http://192.168.1.42:8080/appform/ws/jobs/flistbyid/{jobid}?token=...
            String queryUrl = HttpConfig.notCplusTaskStateQuery+jobId;
            JSONObject httpResult = JSONObject.fromObject(HttpRequest.sendGet(queryUrl,"token="+token));
            //该任务属于非c++平台的计算任务，并且此时已经结束，产生日志文件，需要进行记录
            if (httpResult.getString("result").equals("success")) {
                JSONObject urlArray = httpResult.getJSONArray("data").getJSONObject(0);
                result =  urlArray.getString("path");
            } else
            {
                //该任务要么是c++平台的计算任务，通过上述接口无法查询到状态，要么是非C++平台计算任务，但目前暂时没有结果
                return null;
            }
        }else{
            // 日志记录
            UserLogUtil.dbLog(LogEnum.system, LogEnum.query,
                    "-2", "系统请求token时出现错误");
        }
        return result;
    }

    /**
     * 下载运行任务的日志文件的接口
     * 输入参数：
     * token: 调度token
     * path: 日志文件所在的路径
     * 输出参数：
     * <data contentType="application/x-msdownload" contentLength="5573"><![CDATA[
     * ……
     * 日志文件内容
     * ……
     * ]]></data>
     * @param path：调用queryLogFileUrl方法的到的："path": "/apps/jhinno/jhappform/spoolers/jhadmin/cd35183a-a6b5-424d-b_uiAlgorithm_1_jhadmin_1522390330804/output.6084.txt"
     * @return
     */
    public static String downloadLogFile(String path)
    {
        /*boolean result = false;
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        //例子：D:/JCPT_files/socketLog/2018-06-28-15-13-06-测试.txt
        String newFilePath = HttpConfig.socketLogFileUri+sf.format(new Date())+"-"+
                path.substring(path.lastIndexOf("/")+1,path.length());
        String token = TokenValue.TOKEN.getTokenValue(HttpConfig.userName,HttpConfig.passWord);
        if(token!=null) {
            String param = "token="+token+"&path="+path;
            result = HttpRequest.downloadFile(HttpConfig.logFileDownloadUrl, param, newFilePath);
        }
        return result?newFilePath:null;*/
    	return downloadLogFile(path,null);
    }
    public static String downloadLogFile(String path,String jobId){
    	boolean result = false;
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        //例子：D:/JCPT_files/socketLog/2018-06-28-15-13-06-测试.txt
        String newFilePath /*= HttpConfig.socketLogFileUri+sf.format(new Date())+"-"+
                path.substring(path.lastIndexOf("/")+1,path.length())*/;
        if(jobId!=null){     
        		newFilePath= HttpConfig.socketLogFileUri+jobId+".log";
        	}else{
        		newFilePath = HttpConfig.socketLogFileUri+sf.format(new Date())+   "-"   +  path.substring(path.lastIndexOf("/")+1,path.length());
        	}
        String token = TokenValue.TOKEN.getTokenValue(HttpConfig.userName,HttpConfig.passWord);
        if(token!=null) {
            String param = "token="+token+"&path="+path;
            result = HttpRequest.downloadFile(HttpConfig.logFileDownloadUrl, param, newFilePath);
        }
      return result?newFilePath:null;
    }

}
